package gov.pbc.nn.kjgl.software.view;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import gov.pbc.nn.core.utils.FileUtils;
import gov.pbc.nn.kjgl.archive.dao.ArchivesInputDao;
import gov.pbc.nn.kjgl.entity.Project;
import gov.pbc.nn.kjgl.entity.ProjectFile;
import gov.pbc.nn.kjgl.maintenance.entity.SysMaterial;
import gov.pbc.nn.kjgl.software.dao.ProjectBackupDao;
import gov.pbc.nn.kjgl.software.dao.ProjectBackupJdbcDao;
import gov.pbc.nn.kjgl.software.dao.ProjectDao;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.dorado.annotation.DataProvider;
import com.bstek.dorado.annotation.Expose;
import com.bstek.dorado.core.Configure;
import com.bstek.dorado.data.provider.Criteria;
import com.bstek.dorado.data.provider.Page;
import com.bstek.dorado.uploader.DownloadFile;
import com.bstek.dorado.uploader.UploadFile;
import com.bstek.dorado.uploader.annotation.FileProvider;
import com.bstek.dorado.uploader.annotation.FileResolver;
import com.itextpdf.text.pdf.codec.Base64.OutputStream;

/**
 * 文件报备的业务逻操作
 * 
 * @author jack.zhao
 * 
 */
@Component("projectBackupPR")
public class ProjectBackupPR {
	@Autowired
	private ProjectBackupDao projectBackupDao;
	@Autowired
	private ArchivesInputDao archivesInputDao;
	@Autowired
	private ProjectDao projectDao;
	
	@Autowired
	private ProjectBackupJdbcDao backupJdbcDao;

	/**
	 * 查询所有的project
	 * 
	 * @auther jack.zhao
	 * @param page
	 * 
	 */
	@DataProvider
	public void getAll(Page<Project> page, Criteria criteria) {
		backupJdbcDao.getPageJdbcAll(page, criteria);
//		this.projectBackupDao.getPageAll(page, criteria);
	}

	@DataProvider
	public String getxywqsh(String id) {
		ProjectFile projectFile = this.projectBackupDao.get(id, ProjectFile.class);
		if (projectFile == null) {
			return null;
		} else {
			return projectFile.getFileName();
		}

	}

	/**
	 * 根据id得到ProjectFile的文件
	 * 
	 * @auther jack.zhao
	 * @param pid
	 * @return
	 * 
	 */
	@DataProvider
	public ProjectFile getByProjectId(String pid) {
		return projectBackupDao.getByProjectId(pid);
	}

	/**
	 * 上传文件
	 * 
	 * @auther jack.zhao
	 * @param file
	 * @param parameter
	 * @return
	 * @throws Exception
	 * 
	 */
	@FileResolver
	@Transactional
	public String process2(UploadFile file, Map<String, Object> parameter) throws Exception {
		String name = (String) parameter.get("name");
		// String pid = (String) parameter.get("pid");
		String type = (String) parameter.get("type");
		String id = (String) parameter.get("id");

		if (StringUtils.isEmpty(type)) {
			throw new Exception("文件上传类型为空");
		}
		String basePath = Configure.getString("WENJIAN_FILE_UPLOAD_PATH");
		if (StringUtils.isEmpty(basePath)) {
			throw new IllegalArgumentException("必须指定档案文件上传的基本地址");
		}
		String returnValue = "";
		String pathArr = getFileNameByType(Integer.valueOf(type));
		try {
			// if (projectBackupDao.check(name, id)) {
			Path path = Paths.get(basePath, pathArr);
			if (!Files.isDirectory(path)) {
				path = Files.createDirectories(path);
			}
			// path = path.resolve(file.getFileName());
			path = path.resolve(UUID.randomUUID().toString());
			if (projectBackupDao.check(name, path.toString())) {
				File destFile = Files.createFile(path).toFile();
				// 保存projectFile表格，type设置成0，0是立项的意思
				ProjectFile entity = new ProjectFile();
				entity.setPath(path.toString());
				entity.setFileName(file.getFileName());
				entity.setOwnerId(id);
				entity.setType(0);
				projectBackupDao.save(entity);
				// 关联保存到对应的字段
				saveProjectBy(Integer.valueOf(type), entity.getId(), id);
				file.transferTo(destFile);
				returnValue = entity.getId();
			} else {
				throw new Exception("存在重复的文件！");
			}
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return returnValue;
	}

	@FileProvider
	public DownloadFile download(Map<String, String> parameter) throws IOException {
		ProjectFile pfile = projectDao.getProjectFileById(parameter.get("id"));
		String fileName = pfile.getFileName();
		String path = pfile.getPath();
		InputStream stream = new FileInputStream(path);
		DownloadFile file = new DownloadFile(fileName, stream);
		return file;
	}

	/**
	 * 根据type更新合适的project
	 * 
	 * @auther jack.zhao
	 * @param type
	 * @param entityId
	 * @param id
	 * 
	 */
	private void saveProjectBy(Integer type, String entityId, String id) {
		Project project = projectDao.getProjectById(id);
		if (type == 0) {
			project.setYwxqfxbgId(entityId);
		} else if (type == 1) {
			project.setXxhxmjysId(entityId);
		} else if (type == 2) {
			project.setXtztjsfaId(entityId);
		} else if (type == 3) {
			project.setOtherId(entityId);
		}
		this.projectDao.update(project);
	}

	/**
	 * 根据合适的类型返回合适的字符串，该字符串表示文件存的路径
	 * 
	 * @auther jack.zhao
	 * @param type
	 * @return
	 * 
	 */
	private String getFileNameByType(Integer type) {
		String returnVale = null;
		switch (type) {
		case 0:
			returnVale = "业务需求分析报告";
			break;
		case 1:
			returnVale = "信息化项目建议书";
			break;
		case 2:
			returnVale = "系统总体技术方案";
			break;
		case 3:
			returnVale = "其他";
			break;

		}
		return "项目报备文件/" + returnVale;
	}

	/**
	 * 根据id删除文件
	 * 
	 * @auther jack.zhao
	 * @param pid
	 * @throws IOException
	 * 
	 */
	@Expose
	@Transactional
	public void deleteProjectFile(String pid) throws IOException {
		projectBackupDao.delProjectFile(pid);
	}

	/**
	 * 打包下载文件
	 * 
	 * @auther jack.zhao
	 * @param parameter
	 * @return
	 * @throws IOException
	 * 
	 */
	@FileProvider
	public DownloadFile downloadPackage(Map<String, String> parameter) throws IOException {
		String string = parameter.get("ids");
		String[] split = string.split(",");
		List<String> asList = Arrays.asList(split);
		Path path = getPath(asList);
		InputStream stream = new FileInputStream(path.toString());
		DownloadFile file = new DownloadFile("项目工程资料文件.zip", stream);
		return file;
	}

	public static void deleteAllFilesOfDir(File path) {
		if (!path.exists())
			return;
		if (path.isFile()) {
			path.delete();
			return;
		}
		File[] files = path.listFiles();
		for (int i = 0; i < files.length; i++) {
			deleteAllFilesOfDir(files[i]);
		}
		path.delete();
	}

	public Path getPath(List<String> list) throws IOException {
		String folder = System.getProperty("java.io.tmpdir");
		Path destDir = Paths.get(folder + File.separator + "projectZipTemp");
		List<Path> tempZip = new ArrayList<Path>();

		for (String id : list) {
			Project project = this.projectBackupDao.get(id, Project.class);
			Format format = new SimpleDateFormat("yyyyMMdd");
			String projectName = project.getName() + format.format(project.getCreateDate());

			Path tempPath = Paths.get(folder + "projectTemp" + File.separator + projectName);

			deleteAllFilesOfDir(tempPath.toFile());

			List<Path> temps = new ArrayList<Path>();

			// 业务需求分析书
			String businessRequirementsId = project.getBusinessRequirementsId();
			if (StringUtils.isNotBlank(businessRequirementsId)) {
				ProjectFile projectFile = this.projectBackupDao.get(businessRequirementsId, ProjectFile.class);
				Path transToPaths = this.transToPaths(projectFile, projectName, 4);
				if (transToPaths != null) {
					temps.add(transToPaths);
				}
			}

			// 业务需求分析报告
			String ywxqfxbgid = project.getYwxqfxbgId();
			if (StringUtils.isNotBlank(ywxqfxbgid)) {
				ProjectFile ywProjectFile = this.projectBackupDao.get(ywxqfxbgid, ProjectFile.class);
				Path transToPaths = this.transToPaths(ywProjectFile, projectName, 0);
				if (transToPaths != null) {
					temps.add(transToPaths);
				}
			}

			// 信息化项目建议书
			String xxhxmjysid = project.getXxhxmjysId();
			if (StringUtils.isNotBlank(xxhxmjysid)) {
				ProjectFile xxProjectFile = this.projectBackupDao.get(xxhxmjysid, ProjectFile.class);

				Path transToPaths = this.transToPaths(xxProjectFile, projectName, 1);
				if (transToPaths != null) {
					temps.add(transToPaths);
				}
			}

			// 系统总体技术方案
			String xtztjsfaid = project.getXtztjsfaId();
			if (StringUtils.isNotBlank(xtztjsfaid)) {
				ProjectFile xtProjectFile = this.projectBackupDao.get(xtztjsfaid, ProjectFile.class);

				Path transToPaths = this.transToPaths(xtProjectFile, projectName, 2);
				if (transToPaths != null) {
					temps.add(transToPaths);
				}
			}

			// 其他(多个打包上传)
			String otherid = project.getOtherId();
			if (StringUtils.isNotBlank(otherid)) {
				ProjectFile qtProjectFile = this.projectBackupDao.get(otherid, ProjectFile.class);

				Path transToPaths = this.transToPaths(qtProjectFile, projectName, 3);
				if (transToPaths != null) {
					temps.add(transToPaths);
				}
			}
			// 依然先删除
			String name = destDir.toString() + File.separator + projectName + ".zip";
			this.deleteDirtery(name);

			tempZip.add(FileUtils.compress(projectName, destDir, tempPath));
		}
		Path[] array = new Path[tempZip.size()];

		// 每次打包必须先删除文件
		String name = destDir.toString() + File.separator + "项目工程资料文件.zip";
		this.deleteDirtery(name);

		Path compress = FileUtils.compress("项目工程资料文件", destDir, tempZip.toArray(array));

		return compress;
	}

	public void deleteDirtery(String name) {
		File f = new File(name);
		if (f.exists()) {
			f.delete();
		}
	}

	public Path transToPaths(ProjectFile projectFile, String projectName, Integer type) throws IOException {
		String folder = System.getProperty("java.io.tmpdir");
		String filePath = projectFile.getPath();

		File pFilePath = new File(filePath);
		if (!pFilePath.exists()) {
			return null;
		}
		InputStream in = new FileInputStream(filePath);
		Path temp = Paths.get(folder + "projectTemp" + File.separator + projectName + File.separator + getFileNameByType2(type));
		Path target = Paths.get(folder + "projectTemp" + File.separator + projectName + File.separator + getFileNameByType2(type) + File.separator + projectFile.getFileName());
		// 创建新文件家

		if (!temp.toFile().exists()) {
			temp.toFile().mkdirs();
		}
		if (!target.toFile().exists()) {
			target.toFile().createNewFile();
		}
		Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING);

		return target;
	}

	private String getFileNameByType2(Integer type) {
		String returnVale = null;
		switch (type) {
		case 0:
			returnVale = "业务需求分析报告";
			break;
		case 1:
			returnVale = "信息化项目建议书";
			break;
		case 2:
			returnVale = "系统总体技术方案";
			break;
		case 3:
			returnVale = "其他";
			break;
		case 4:
			returnVale = "业务需求书";
			break;
		}
		return returnVale;
	}

	@Expose
	public boolean checkOper(String id) {
		/*Project p = this.projectBackupDao.get(id, Project.class);
		String createUname = p.getCreateUser();
		String username = ContextHolder.getLoginUser().getUsername();
		if (createUname.equals(username)) {
			return true;
		} else {
			return false;
		}*/
		String username = ContextHolder.getLoginUser().getUsername();
		if (this.backupJdbcDao.isInkjMember(username, id)){
			return true;
		} else {
			return false;
		}
		

	}

}
